<!DOCTYPE html>
<html>

<head>
	<title>3D Model Viewer Demo</title>
	<meta charset="UTF-8" />
	<script src="https://cdn.babylonjs.com/babylon.js"></script>
	<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
	<style>
		body {
			overflow: hidden;
			margin: 0;
			padding: 0;
			font-family: Arial, sans-serif;
		}
		#renderCanvas {
			width: 100%;
			height: 100vh;
			touch-action: none;
		}
		.control-button {
			position: absolute;
			z-index: 1000;
			border: 1px solid #333;
			border-radius: 50%;
			background: rgb(255, 255, 255, 0.9);
			box-shadow: 0 2px 4px rgb(0, 0, 0, 0.3);
			cursor: pointer;
			transition: all 0.3s ease;
		}
		.control-button:hover {
			box-shadow: 0 3px 6px rgb(0, 0, 0, 0.4);
			transform: scale(1.1);
		}
	</style>
</head>

<body>
	<canvas id="renderCanvas"></canvas>

	<!-- 播放按钮 -->
	<div id="playButton" style="
        position: absolute;
        left: 50%;
        top: 50%;
        z-index: 1000;
        cursor: pointer;
        transform: translate(-50%, -50%);
      ">
		<svg width="80" height="80" viewBox="0 0 80 80" style="filter: drop-shadow(0 4px 8px rgb(0, 0, 0, 0.3))">
			<circle cx="40" cy="40" r="35" fill="rgba(255,255,255,0.9)" stroke="#333" stroke-width="2" />
			<polygon points="32,25 32,55 55,40" fill="#333" />
		</svg>
	</div>

	<!-- 白膜切换按钮 -->
	<div id="whiteModeButton" class="control-button" style="
        display: none;
        left: 50%;
        bottom: 10px;
        justify-content: center;
        align-items: center;
        width: 20px;
        height: 20px;
        transform: translateX(-50%);
      ">
		<!-- 白膜模式图标 -->
		<svg id="whiteModeIcon" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2">
			<circle cx="12" cy="12" r="10" />
			<path d="M12 2a10 10 0 0 0 0 20z" />
		</svg>
		<!-- 纹理模式图标 -->
		<svg id="textureIcon" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" style="display: none">
			<rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
			<path d="M9 9h6v6H9z" />
			<path d="M3 15l6-6" />
			<path d="M21 9l-6 6" />
		</svg>
	</div>

	<script>
		// 解析URL参数获取src
		function getUrlParameter(name) {
			const urlParams = new URLSearchParams(window.location.search);
			return urlParams.get(name);
		}

		// 获取模型文件路径
		const modelSrc = getUrlParameter("src");

		// 初始化Babylon.js
		const canvas = document.getElementById("renderCanvas");
		const engine = new BABYLON.Engine(canvas, true);

		// 自动旋转控制变量
		let autoRotate = true;
		let lastInteractionTime = Date.now();
		const AUTO_ROTATE_DELAY = 3000; // 3秒后开始自动旋转
		let lastTime = Date.now(); // 用于计算时间差
		const ROTATION_SPEED = 0.5; // 每秒旋转弧度数

		// 手动控制变量
		let isPointerDown = false;
		let lastPointerX = 0;
		let lastPointerY = 0;

		// 白膜模式控制变量
		let isWhiteMode = false;
		let originalMaterials = new Map(); // 存储原始材质
		let loadedMeshes = []; // 存储加载的模型网格

		// 创建场景
		const createScene = function() {
			const scene = new BABYLON.Scene(engine);

			// 创建相机
			const camera = new BABYLON.ArcRotateCamera(
				"camera",
				-Math.PI / 2,
				Math.PI / 2.5,
				10,
				BABYLON.Vector3.Zero(),
				scene
			);

			camera.fov = Math.PI / 16;

			scene.activeCamera = camera;
			scene.activeCamera.setTarget(BABYLON.Vector3.Zero());

			// 限制相机移动范围
			camera.lowerRadiusLimit = 1;
			camera.upperRadiusLimit = 100;
			camera.lowerBetaLimit = 0.1;
			camera.upperBetaLimit = Math.PI - 0.1;

			// 创建光源
			const light = new BABYLON.HemisphericLight(
				"light",
				new BABYLON.Vector3(0, 1, 0),
				scene
			);
			light.intensity = 1.0;
			light.diffuse = new BABYLON.Color3(1, 1, 0.9); // 暖白色

			// 添加定向光（主光源）- 调整为正面照射
			const directionalLight = new BABYLON.DirectionalLight(
				"dirLight",
				new BABYLON.Vector3(0, -0.5, -1), // 从正前方稍微偏上照射
				scene
			);
			directionalLight.intensity = 1.5; // 增强主光源强度
			directionalLight.diffuse = new BABYLON.Color3(1, 1, 1);
			directionalLight.specular = new BABYLON.Color3(0.4, 0.4, 0.4);

			// 添加补光（从右前方）
			const fillLight = new BABYLON.DirectionalLight(
				"fillLight",
				new BABYLON.Vector3(0.5, -0.3, -0.8), // 从右前方照射
				scene
			);
			fillLight.intensity = 0.8; // 增强补光强度
			fillLight.diffuse = new BABYLON.Color3(0.9, 0.95, 1); // 稍微偏冷色调

			// 添加背光（轮廓光）- 调整为从后方照射
			const rimLight = new BABYLON.DirectionalLight(
				"rimLight",
				new BABYLON.Vector3(0, 0, 1), // 从后方照射，形成轮廓光
				scene
			);
			rimLight.intensity = 0.5; // 适度的轮廓光强度
			rimLight.diffuse = new BABYLON.Color3(0.8, 0.9, 1);

			// 添加点光源（动态光源）- 调整位置到前方
			const pointLight = new BABYLON.PointLight(
				"pointLight",
				new BABYLON.Vector3(0, 3, -5), // 移动到前方偏上位置
				scene
			);
			pointLight.intensity = 1.0; // 增强点光源强度
			pointLight.diffuse = new BABYLON.Color3(1, 0.95, 0.8); // 暖色调
			pointLight.range = 25;

			// 添加聚光灯（重点照明）- 调整为正面照射
			const spotLight = new BABYLON.SpotLight(
				"spotLight",
				new BABYLON.Vector3(2, 5, -3), // 从前方偏右上照射
				new BABYLON.Vector3(-0.3, -1, 0.5), // 照射方向指向模型中心
				Math.PI / 4, // 稍微扩大照射角度
				2,
				scene
			);
			spotLight.intensity = 1.2; // 增强聚光灯强度
			spotLight.diffuse = new BABYLON.Color3(1, 1, 1);
			spotLight.specular = new BABYLON.Color3(0.5, 0.5, 0.5);

			// 添加环境光增强
			scene.ambientColor = new BABYLON.Color3(0.4, 0.4, 0.45); // 进一步增强环境光

			// 创建背景高光效果
			const backgroundSphere = BABYLON.MeshBuilder.CreateSphere(
				"backgroundSphere", {
					diameter: 200,
				},
				scene
			);
			const backgroundMaterial = new BABYLON.StandardMaterial(
				"backgroundMaterial",
				scene
			);

			// 创建渐变纹理作为背景
			const backgroundTexture = new BABYLON.DynamicTexture(
				"backgroundTexture", {
					width: 512,
					height: 512,
				},
				scene
			);
			const ctx = backgroundTexture.getContext();

			// 创建径向渐变高光效果
			const gradient = ctx.createRadialGradient(256, 256, 0, 256, 256, 256);
			gradient.addColorStop(0, "rgba(255, 255, 255, 0.8)"); // 中心白色高光
			gradient.addColorStop(0.3, "rgba(200, 220, 255, 0.6)"); // 淡蓝色过渡
			gradient.addColorStop(0.7, "rgba(100, 150, 200, 0.4)"); // 深蓝色
			gradient.addColorStop(1, "rgba(50, 80, 120, 0.2)"); // 边缘深色

			ctx.fillStyle = gradient;
			ctx.fillRect(0, 0, 512, 512);
			backgroundTexture.update();

			// 配置背景材质
			backgroundMaterial.diffuseTexture = backgroundTexture;
			backgroundMaterial.emissiveTexture = backgroundTexture;
			backgroundMaterial.emissiveColor = new BABYLON.Color3(0.3, 0.3, 0.3);
			backgroundMaterial.backFaceCulling = false; // 显示内表面
			backgroundMaterial.disableLighting = true; // 不受光照影响

			backgroundSphere.material = backgroundMaterial;
			backgroundSphere.infiniteDistance = true; // 始终在远处
			backgroundSphere.renderingGroupId = 0; // 最先渲染

			// 动态光源效果（可选）
			let lightAnimation = 0;
			scene.registerBeforeRender(() => {
				lightAnimation += 0.02;
				// 点光源在前方区域轻微摆动
				pointLight.position.x = Math.sin(lightAnimation) * 1.5;
				pointLight.position.z = -5 + Math.cos(lightAnimation) * 0.5; // 保持在前方
				// 聚光灯强度变化
				spotLight.intensity = 1.0 + Math.sin(lightAnimation * 0.5) * 0.3;
			});

			// 监听用户交互事件
			const onUserInteraction = () => {
				autoRotate = false;
				lastInteractionTime = Date.now();
			};

			// 手动实现相机控制
			canvas.addEventListener("pointerdown", (event) => {
				isPointerDown = true;
				lastPointerX = event.clientX;
				lastPointerY = event.clientY;
				onUserInteraction();
				canvas.setPointerCapture(event.pointerId);
			});

			canvas.addEventListener("pointermove", (event) => {
				if (isPointerDown) {
					const deltaX = event.clientX - lastPointerX;
					const deltaY = event.clientY - lastPointerY;

					// 旋转相机
					camera.alpha -= deltaX * 0.01;
					camera.beta -= deltaY * 0.01; // 改为减号，修正上下拖拽方向

					// 限制beta角度
					camera.beta = Math.max(
						camera.lowerBetaLimit,
						Math.min(camera.upperBetaLimit, camera.beta)
					);

					lastPointerX = event.clientX;
					lastPointerY = event.clientY;
					onUserInteraction();
				}
			});

			canvas.addEventListener("pointerup", (event) => {
				isPointerDown = false;
				lastInteractionTime = Date.now();
				canvas.releasePointerCapture(event.pointerId);
			});

			// 滚轮缩放
			canvas.addEventListener("wheel", (event) => {
				event.preventDefault();
				const delta = event.deltaY > 0 ? 1.1 : 0.9;
				camera.radius *= delta;
				camera.radius = Math.max(
					camera.lowerRadiusLimit,
					Math.min(camera.upperRadiusLimit, camera.radius)
				);
				onUserInteraction();
			});

			// 自动旋转逻辑
			scene.registerBeforeRender(() => {
				const currentTime = Date.now();
				const deltaTime = (currentTime - lastTime) / 1000; // 转换为秒
				lastTime = currentTime;

				// 超过延迟时间后开始自动旋转
				if (
					!autoRotate &&
					currentTime - lastInteractionTime > AUTO_ROTATE_DELAY
				) {
					autoRotate = true;
				}

				// 执行自动旋转
				if (autoRotate) {
					// 基于时间的自动旋转，确保旋转速度恒定
					camera.alpha += ROTATION_SPEED * deltaTime;
				}
			});

			// 白膜切换功能
			function toggleWhiteMode() {
				isWhiteMode = !isWhiteMode;
				const whiteModeIcon = document.getElementById("whiteModeIcon");
				const textureIcon = document.getElementById("textureIcon");
				const button = document.getElementById("whiteModeButton");

				if (isWhiteMode) {
					// 切换到白膜模式
					loadedMeshes.forEach((mesh) => {
						if (mesh.material) {
							// 保存原始材质
							if (!originalMaterials.has(mesh.id)) {
								originalMaterials.set(mesh.id, mesh.material);
							}

							// 创建白色材质（进一步降低亮度）
							const whiteMaterial = new BABYLON.StandardMaterial(
								"whiteMaterial_" + mesh.id,
								scene
							);
							whiteMaterial.diffuseColor = new BABYLON.Color3(
								0.45,
								0.45,
								0.45
							); // 从0.6降低到0.45
							whiteMaterial.specularColor = new BABYLON.Color3(
								0.01,
								0.01,
								0.01
							); // 进一步降低高光
							whiteMaterial.roughness = 0.98; // 增加粗糙度
							whiteMaterial.ambientColor = new BABYLON.Color3(0.2, 0.2, 0.2); // 降低环境光反射

							// 应用白色材质
							mesh.material = whiteMaterial;
						}
					});

					// 在白膜模式下降低光源强度
					light.intensity = 0.6; // 从1.0降低到0.6
					directionalLight.intensity = 0.8; // 从1.5降低到0.8
					fillLight.intensity = 0.4; // 从0.8降低到0.4
					pointLight.intensity = 0.5; // 从1.0降低到0.5
					spotLight.intensity = 0.6; // 从1.2降低到0.6

					// 切换图标显示
					whiteModeIcon.style.display = "none";
					textureIcon.style.display = "block";
					button.style.backgroundColor = "rgba(200, 200, 200, 0.9)";
				} else {
					// 恢复原始纹理
					loadedMeshes.forEach((mesh) => {
						if (originalMaterials.has(mesh.id)) {
							mesh.material = originalMaterials.get(mesh.id);
						}
					});

					// 恢复原始光源强度
					light.intensity = 1.0;
					directionalLight.intensity = 1.5;
					fillLight.intensity = 0.8;
					pointLight.intensity = 1.0;
					spotLight.intensity = 1.2;

					// 切换图标显示
					whiteModeIcon.style.display = "block";
					textureIcon.style.display = "none";
					button.style.backgroundColor = "rgba(255, 255, 255, 0.9)";
				}
			}

			// 加载3D模型的函数
			function loadModel() {
				// 隐藏播放按钮
				document.getElementById("playButton").style.display = "none";
				// 显示白膜切换按钮
				document.getElementById("whiteModeButton").style.display = "flex";

				BABYLON.SceneLoader.ImportMesh(
					"",
					"",
					modelSrc,
					scene,
					function(meshes) {
						// 保存加载的网格
						loadedMeshes = meshes;

						// 模型加载成功后的处理
						if (meshes.length > 0) {
							// 计算模型边界框
							let min = new BABYLON.Vector3(
								Number.MAX_VALUE,
								Number.MAX_VALUE,
								Number.MAX_VALUE
							);
							let max = new BABYLON.Vector3(
								-Number.MAX_VALUE,
								-Number.MAX_VALUE,
								-Number.MAX_VALUE
							);

							meshes.forEach((mesh) => {
								if (mesh.getBoundingInfo) {
									const meshMin =
										mesh.getBoundingInfo().boundingBox.minimumWorld;
									const meshMax =
										mesh.getBoundingInfo().boundingBox.maximumWorld;
									min = BABYLON.Vector3.Minimize(min, meshMin);
									max = BABYLON.Vector3.Maximum(max, meshMax);
								}
							});

							const center = BABYLON.Vector3.Center(min, max);
							const size = max.subtract(min);
							const maxSize = Math.max(size.x, size.y, size.z);

							camera.setTarget(center);
							camera.radius = maxSize * 2;

							// 直接放大模型，而不是调整相机
							meshes.forEach((mesh) => {
								mesh.scaling = new BABYLON.Vector3(3, 3, 3); // 放大3倍
							});

							// 调整相机限制范围
							camera.lowerRadiusLimit = maxSize * 0.5;
							camera.upperRadiusLimit = maxSize * 5;
						}
					},
					function(progress) {
						console.log("Loading progress:", progress);
					},
					function(error) {
						console.error("Error loading model:", error);
					}
				);
			}

			// 添加播放按钮点击事件
			document
				.getElementById("playButton")
				.addEventListener("click", loadModel);

			// 添加白膜切换按钮点击事件
			document
				.getElementById("whiteModeButton")
				.addEventListener("click", toggleWhiteMode);

			return scene;
		};

		// 创建场景并开始渲染
		const scene = createScene();

		// 渲染循环
		engine.runRenderLoop(function() {
			scene.render();
		});

		// 窗口大小调整
		window.addEventListener("resize", function() {
			engine.resize();
		});
	</script>
</body>

</html>